﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net;
using System.Web.UI.WebControls;
using System.Text.RegularExpressions;
using System.Web.Script.Serialization;
using LootPoints.Tools;

namespace LootPoints.Warcraft
{
    public enum Region { eu, us };

    public class BattleNet
    {
        private Region region = Region.eu;
        private string realm = "Defias%20Brotherhood";
        private string guild = "Exploding%20Sheep%20Inc";

        public Region Region
        {
            get { return region; }
            set { region = value; }
        }
        public string Realm
        {
            get { return realm; }
            set { realm = value; }
        }
        public string Guild
        {
            get { return guild; }
            set { guild = value; }
        }

        /// <summary>
        /// [0]: name, [1]: race, [2]: class, [3]: level, [4]: bettlegroup, [5]: achievementpoints, [6]: gender
        /// </summary>
        /// <param name="characterName"></param>
        /// <returns></returns>
        public string[] GetCharacter(string characterName)
        {
            Dictionary<int, string> races = GetRaces();
            Dictionary<int, string> classes = GetClasses();

            WebClient client = new WebClient();
            string result = client.DownloadString("http://" + region.ToString() + ".battle.net/api/wow/character/" + realm + "/" + characterName);

            // Convert the result to a filtered list
            List<string> filteredValues = FilterValues(result);

            string[] character = new string[7];
            character[0] = characterName;

            for (int i = 0; i + 1 < filteredValues.Count; i++)
            {
                if (filteredValues[i] == "race") character[1] = races[Convert.ToInt32(filteredValues[i + 1])];
                if (filteredValues[i] == "class") character[2] = classes[Convert.ToInt32(filteredValues[i + 1])];
                if (filteredValues[i] == "level") character[3] = filteredValues[i + 1];
                if (filteredValues[i] == "battlegroup") character[4] = filteredValues[i + 1];
                if (filteredValues[i] == "achievementPoints") character[5] = filteredValues[i + 1];
                if (filteredValues[i] == "gender")
                {
                    if (filteredValues[i + 1] == "0") character[6] = "male";
                    else character[6] = "female";
                }
            }

            return character;
        }

        public List<string> GetFullCharacter(string charactername)
        {
            Dictionary<int, string> races = GetRaces();
            Dictionary<int, string> classes = GetClasses();

            WebClient client = new WebClient();
            string result = client.DownloadString("http://" + region.ToString() + ".battle.net/api/wow/character/" + realm + "/" + charactername);

            // Convert the result to a filtered list
            List<string> filteredValues = FilterValues(result);

            Dictionary<string, string> details = new Dictionary<string, string>();
            details.Add("name", charactername);

            List<List<string>> feeds = new List<List<string>>();

            bool infeed = false;
            bool inprogression = false;
            for (int i = 0; i + 1 < filteredValues.Count; i++)
            {
                if (filteredValues[i] == "race") details.Add("race",races[Convert.ToInt32(filteredValues[i + 1])]);
                if (filteredValues[i] == "class") details.Add("class", classes[Convert.ToInt32(filteredValues[i + 1])]);
                if (filteredValues[i] == "level") details.Add("level", filteredValues[i + 1]);
                if (filteredValues[i] == "battlegroup") details.Add("battlegroup", filteredValues[i + 1]);
                if (filteredValues[i] == "achievementPoints") details.Add("achievementpoints", filteredValues[i + 1]);
                if (filteredValues[i] == "gender")
                {
                    if (filteredValues[i + 1] == "0") details.Add("gender", "male");
                    else details.Add("gender", "female");
                }

                if (infeed)
                {
                    if (filteredValues[i] == "type")
                    {
                        List<string> feed = new List<string>();

                        for (int j = i; j < filteredValues.Count; j++)
			            {

			            }

                        i++;
                        feed.Add(filteredValues[i]); //type
                        i++; i++;
                        feed.Add(filteredValues[i]); //timestamp
                        i++; i++; i++; i++; i++;
                        feed.Add(filteredValues[i]); //achievement
                    }
                }

                if (inprogression)
                {
                }

                if (filteredValues[i] == "feed") { infeed = true; inprogression = false; }
                if (filteredValues[i] == "progression") { inprogression = true; infeed = false; }
            }

            return null;
        }

        /// <summary>
        /// Gets all guildmembers from BattleNet and all details.
        /// </summary>
        /// <returns>Dictionary with Key: Charactername, Value[0]: Race, Value[1]: Class, Value[2]: Level, Value[3]: Rank</returns>
        public Dictionary<string, string[]> GetGuildMembers()
        {
            #region Fill specslist
            List<string> Specs = new List<string>()
            {
                "Blood", 
                "Frost", 
                "Unholy", 
                "Restoration", 
                "Balance", 
                "Feral", 
                "Beast Mastery", 
                "Marksmanship", 
                "Survival", 
                "Arcane", 
                "Fire", 
                "Holy", 
                "Protection", 
                "Retribution", 
                "Discipline", 
                "Shadow", 
                "Assassination", 
                "Combat", 
                "Subtlety", 
                "Elemental", 
                "Enhancement", 
                "Affliction", 
                "Demonology", 
                "Destruction", 
                "Arms", 
                "Fury",
                "Brewmaster",
                "Mistweaver",
                "Windwalker"
            };
            #endregion
            Dictionary<int, string> races = GetRaces();
            Dictionary<int, string> classes = GetClasses();

            WebClient client = new WebClient();
            client.Encoding = System.Text.Encoding.UTF8;
            string result = client.DownloadString("http://" + region.ToString() + ".battle.net/api/wow/guild/" + realm + "/" + guild + "?fields=members");

            // Convert the result to a filtered list
            List<string> filteredValues = FilterValues(result);

            // Skip the guildname
            int i = 0;
            while (filteredValues[i] != "name") i++;
            i++;

            // Temp variabels
            string character = "";
            string clas = "";
            string race = "";
            string level = "";

            Dictionary<string, string[]> members = new Dictionary<string, string[]>();

            for (; i + 1 < filteredValues.Count; i++)
            {
                if (filteredValues[i] == "name")
                {
                    if (!Specs.Contains(filteredValues[i + 1]))
                    {
                        character = filteredValues[i + 1];
                    }
                }

                if (filteredValues[i] == "class") clas = classes[Convert.ToInt32(filteredValues[i + 1])];
                if (filteredValues[i] == "race") race = races[Convert.ToInt32(filteredValues[i + 1])];
                if (filteredValues[i] == "level") level = filteredValues[i + 1];
                
                if (filteredValues[i] == "rank")
                    if (!members.ContainsKey(character))
                        members.Add(character, new string[] { race, clas, level, filteredValues[i + 1] });
            }

            return members;
        }

        /// <summary>
        /// Will get all the races available from BattleNet
        /// </summary>
        /// <returns></returns>
        public Dictionary<int, string> GetRaces()
        {
            WebClient client = new WebClient();
            string result = client.DownloadString("http://" + region + ".battle.net/api/wow/data/character/races");

            // Convert the result to a filtered list
            List<string> filteredValues = FilterValues(result);

            int foundid = 0;
            Dictionary<int, string> races = new Dictionary<int, string>();
            for (int i = 0; i + 1 < filteredValues.Count; i++)
            {
                if (filteredValues[i] == "id") foundid = Convert.ToInt32(filteredValues[i + 1]);
                if (filteredValues[i] == "name") races.Add(foundid, filteredValues[i + 1]);
            }

            return races;
        }

        /// <summary>
        /// Will get all the available classes from BattleNet
        /// </summary>
        /// <returns></returns>
        public Dictionary<int, string> GetClasses()
        {
            WebClient client = new WebClient();
            string result = client.DownloadString("http://" + region + ".battle.net/api/wow/data/character/classes");

            // Convert the result to a filtered list
            List<string> filteredValues = FilterValues(result);

            int foundid = 0;
            Dictionary<int, string> classes = new Dictionary<int, string>();
            for (int i = 0; i + 1 < filteredValues.Count; i++)
            {
                if (filteredValues[i] == "id") foundid = Convert.ToInt32(filteredValues[i + 1]);
                if (filteredValues[i] == "name") classes.Add(foundid, filteredValues[i + 1]);
            }

            return classes;
        }

        /// <summary>
        /// Returns the name of a item, this method can load more if needed
        /// </summary>
        /// <param name="itemId">string name</param>
        /// <returns></returns>
        public string GetItemName(int itemId)
        {
            WebClient client = new WebClient();
            string result = client.DownloadString("http://" + region + ".battle.net/api/wow/item/" + itemId.ToString());

            // Convert the result to a filtered list
            List<string> filteredValues = FilterValues(result);
            
            int i = 0;
            while (filteredValues[i] != "name") i++;

            return filteredValues[i + 1];
        }

        /// <summary>
        /// Filter the downloaded sting into a list of values
        /// </summary>
        /// <param name="result">downloaded string</param>
        /// <returns></returns>
        public List<string> FilterValues(string result)
        {
            // Filtervalues
            char[] splitters = { '"', ',', ':', '[', ']', '{', '}' };

            // Raw values with empty strings for some reason
            string[] rawValues = result.Split(splitters);

            Label convertHulp = new Label();

            // Put the non-empty values in a list
            List<string> filteredValues = new List<string>();
            foreach (string value in rawValues)
            {
                if (value != "")
                {
                    filteredValues.Add(ConvertSpecialChars(value.Replace(@"\", ".")));
                }
            }

            return filteredValues;
        }

        public string ConvertSpecialChars(string input)
        {
            Dictionary<string, string> specials = new Dictionary<string, string>()
            {
                { ".u00C0", "À" }, { ".u00C1", "Á" }, { ".u00C3", "Ã" }, { ".u00C4", "Ä" },
                { ".u00C5", "Å" }, { ".u00C6", "Æ" }, { ".u00C7", "Ç" }, { ".u00C8", "È" },
                { ".u00C9", "É" }, { ".u00CA", "Ê" }, { ".u00CB", "Ë" }, { ".u00CC", "Ì" },
                { ".u00Cd", "Í" }, { ".u00CE", "Î" }, { ".u00CF", "Ï" }, { ".u00D0", "Ð" },
                { ".u00D1", "Ñ" }, { ".u00F5", "õ" }, { ".u00F6", "ö" }, { ".u00F9", "ù" },
                { ".u00A1", "¡" }, { ".u00A2", "¢" }, { ".u00A3", "£" }, { ".u00A4", "¤" },
                { ".u00A5", "¥" }, { ".u00A7", "§" }, { ".u00A8", "¨" }, { ".u00A9", "©" },
                { ".u00AA", "ª" }, { ".u00AC", "¬" }, { ".u00AD", "-" }, { ".u00FD", "ý" },
                { ".u00D3", "Ó" }, { ".u00AB", "«" }, { ".u00D4", "Ô" }, { ".u00D5", "Õ" },
                { ".u00D6", "Ö" }, { ".u00D7", "x" }, { ".u00D8", "Ø" }, { ".u00D9", "Ù" },
                { ".u00DA", "Ú" }, { ".u00D2", "Ò" }, { ".u00DB", "û" }, { ".u00DC", "Ü" },
                { ".u00DD", "Ý" }, { ".u00DF", "ß" }, { ".u00E0", "à" }, { ".u00E1", "á" },
                { ".u00E2", "â" }, { ".u00E3", "ã" }, { ".u00E4", "ä" }, { ".u00E5", "å" },
                { ".u00E6", "æ" }, { ".u00E7", "ç" }, { ".u00E8", "è" }, { ".u00E9", "é" },
                { ".u00EA", "ê" }, { ".u00EB", "ë" }, { ".u00EC", "ì" }, { ".u00ED", "í" },
                { ".u00EE", "î" }, { ".u00EF", "ï" }, { ".u00F1", "ñ" }, { ".u00F2", "ò" },
                { ".u00F3", "ó" }, { ".u00F4", "ô" }, { ".u00FA", "ú" }, { ".u00FB", "Û" },
                { ".u00FC", "ü" }, { ".u00F8", "ø" }
            };

            foreach (string item in specials.Keys)
            {
                if (input.Contains(item))
                {
                    input = input.Replace(item, specials[item]);
                }
            }

            return input;
        }

        // ..............................................

        public dynamic GuildMembers
        {
            get
            {
                WebClient client = new WebClient();
                client.Encoding = System.Text.Encoding.UTF8;
                string json = client.DownloadString("http://" + region.ToString() + ".battle.net/api/wow/guild/" + realm + "/" + guild + "?fields=members");

                var serializer = new JavaScriptSerializer();
                serializer.RegisterConverters(new[] { new DynamicJsonConverter() });
                return serializer.Deserialize(json, typeof(object));
            }
        }

        public dynamic GuildAchievements
        {
            get
            {
                WebClient client = new WebClient();
                client.Encoding = System.Text.Encoding.UTF8;
                string json = client.DownloadString("http://" + region.ToString() + ".battle.net/api/wow/guild/" + realm + "/" + guild + "?fields=achievements");

                var serializer = new JavaScriptSerializer();
                serializer.RegisterConverters(new[] { new DynamicJsonConverter() });
                return serializer.Deserialize(json, typeof(object));
            }
        }

        public dynamic GuildChallenges
        {
            get
            {
                WebClient client = new WebClient();
                client.Encoding = System.Text.Encoding.UTF8;
                string json = client.DownloadString("http://" + region.ToString() + ".battle.net/api/wow/guild/" + realm + "/" + guild + "?fields=challenge");

                var serializer = new JavaScriptSerializer();
                serializer.RegisterConverters(new[] { new DynamicJsonConverter() });
                return serializer.Deserialize(json, typeof(object));
            }
        }
    }
}